package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NCException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CurrentUserHolder;
import com.nineclock.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.dto.SysCompanyUserDTO;
import com.nineclock.dto.SysDepartmentDTO;
import com.nineclock.pojo.*;
import com.nineclock.system.excel.ExcelListener;
import com.nineclock.system.excel.ExcelMember;
import com.nineclock.system.mapper.*;
import com.nineclock.system.service.SysOrganizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Service
@Transactional
public class SysOrganizationServiceImpl implements SysOrganizationService {
    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;
    @Autowired
    SysDepartmentMapper sysDepartmentMapper;

    @Override
    public List<SysCompanyUserDTO> findAllMembers() {
        // 获取当前登录用户
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 组装查询条件, 查询状态为正常的员工信息
        LambdaQueryWrapper<SysCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getCompanyId, companyId)
                .eq(SysCompanyUser::getEnable, "1");
        List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(queryWrapper);

        return BeanHelper.copyWithCollection(sysCompanyUsers, SysCompanyUserDTO.class);
    }

    // 获取组织架构列表
    @Override
    public List<SysDepartmentDTO> findDepartment() {
        // 获取企业Id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 获取顶层目录的列表
        LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
        departmentWrapper.eq(SysDepartment::getCompanyId, companyId);
        departmentWrapper.eq(SysDepartment::getParentId, (long) 0);
        List<SysDepartment> topSysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
        List<SysDepartmentDTO> sysDepartmentDTOS = BeanHelper.copyWithCollection(topSysDepartments, SysDepartmentDTO.class);
        // 递归获取下层数据
        getNextDeparment(sysDepartmentDTOS, companyId);

        return sysDepartmentDTOS;
    }

    // 分页查询部分成员列表
    @Override
    public PageResult<SysCompanyUserDTO> findDepartmentUser(Long departmentId, Integer page, Integer pageSize, String keyword) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 组装查询条件
        LambdaQueryWrapper<SysCompanyUser> companyUserWrapper = new LambdaQueryWrapper<>();
        companyUserWrapper.eq(SysCompanyUser::getCompanyId, companyId);
        if (StrUtil.isNotEmpty(keyword)) {
            companyUserWrapper.eq(SysCompanyUser::getMobile, keyword)
                    .or()
                    .eq(SysCompanyUser::getUserName, keyword)
                    .or()
                    .eq(SysCompanyUser::getWorkNumber, keyword);
        }
        // 递归调用查询所有部门Id的父目录Id
        List<Long> demIds = new ArrayList<>();
        demIds.add(departmentId);
        getDempartmentParentId(demIds, departmentId);
        companyUserWrapper.in(SysCompanyUser::getDepartmentId, demIds);
        // 构建分页查询条件
        Page<SysCompanyUser> pages = new Page<>(page, pageSize);
        pages = sysCompanyUserMapper.selectPage(pages, companyUserWrapper);
        List<SysCompanyUser> records = pages.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            List<SysCompanyUserDTO> sysCompanyUserDTOS = BeanHelper.copyWithCollection(records, SysCompanyUserDTO.class);
            // 封装参数
            sysCompanyUserDTOS.forEach(sysCompanyUserDTO -> {
                // 封装部门名称和部门id
                Long departmentId1 = sysCompanyUserDTO.getDepartmentId();
                String departmentName = sysCompanyUserDTO.getDepartmentName();
                SysDepartmentDTO sysDepartmentDTO = new SysDepartmentDTO();
                sysDepartmentDTO.setId(departmentId1);
                sysDepartmentDTO.setName(departmentName);
                sysCompanyUserDTO.setDepartment(sysDepartmentDTO);
            });
            return new PageResult<>(pages.getTotal(), pages.getPages(), sysCompanyUserDTOS);
        }
        return null;
    }
// 通过当前企业id查询所有部门id
    @Override
    public List<Long> findDepartmentByCompanyId() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 构造查询条件
        LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
        departmentWrapper.eq(SysDepartment::getCompanyId, companyId);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
        List<Long> departmentsIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            for (SysDepartment sysDepartment : sysDepartments) {
                Long id = sysDepartment.getId();
                departmentsIds.add(id);
            }
        }
        return departmentsIds;
    }

    // 获取考勤组下部门相关的员工数量
    @Override
    public Integer findAttendAndCompanyUserCount(List<Long> departmentId) {

        // 获取传递来的所有部门对应的子部门
        List<Long> departIds = new ArrayList<>();
        departIds.addAll(departmentId);
        for (Long id : departmentId) {
            getDempartmentParentId(departIds, id);
        }
        // 去重
        Set<Long> ids = new HashSet<>(departIds);
        // 根据部门Id集合查询所有员工信息
        LambdaQueryWrapper<SysCompanyUser> companyUserWrapper = new LambdaQueryWrapper<>();
        companyUserWrapper.eq(SysCompanyUser::getEnable, (short) 1);
        companyUserWrapper.in(SysCompanyUser::getDepartmentId, ids);
        Integer count = sysCompanyUserMapper.selectCount(companyUserWrapper);
        return count;
    }

    // 获取简单部门列表
    @Override
    public List<DepartmentOrUserSimpleDTO> findDepartmentSimple(Long departmentId, Integer includeMember) {
        List<DepartmentOrUserSimpleDTO> dtoList = new ArrayList<>();
        if (includeMember == 0) {
            // 包含员工
            LambdaQueryWrapper<SysCompanyUser> companyUserWrapper = new LambdaQueryWrapper<>();
            companyUserWrapper.eq(SysCompanyUser::getDepartmentId, departmentId);
            companyUserWrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(companyUserWrapper);
            if (CollectionUtil.isNotEmpty(sysCompanyUsers)) {
                for (SysCompanyUser sysCompanyUser : sysCompanyUsers) {
                    DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                    departmentOrUserSimpleDTO.setId(sysCompanyUser.getId());
                    departmentOrUserSimpleDTO.setName(sysCompanyUser.getUserName());
                    departmentOrUserSimpleDTO.setType(2);
                    dtoList.add(departmentOrUserSimpleDTO);
                }
            }
        }
        // 不包含员工
        LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
        departmentWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentWrapper.eq(SysDepartment::getParentId, departmentId);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            for (SysDepartment sysDepartment : sysDepartments) {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(sysDepartment.getId());
                departmentOrUserSimpleDTO.setName(sysDepartment.getName());
                departmentOrUserSimpleDTO.setType(1);
                dtoList.add(departmentOrUserSimpleDTO);
            }
        }
        return dtoList;
       /* LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
        departmentWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentWrapper.eq(SysDepartment::getParentId, departmentId);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
        List<DepartmentOrUserSimpleDTO> dtoList = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            for (SysDepartment sysDepartment : sysDepartments) {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(sysDepartment.getId());
                departmentOrUserSimpleDTO.setName(sysDepartment.getName());
                departmentOrUserSimpleDTO.setType(1);
                ids.add(sysDepartment.getId());
                dtoList.add(departmentOrUserSimpleDTO);
            }
        }
        for (Long id : ids) {
            LambdaQueryWrapper<SysCompanyUser> companyUserWrapper = new LambdaQueryWrapper<>();
            companyUserWrapper.eq(SysCompanyUser::getDepartmentId, id);
            companyUserWrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(companyUserWrapper);
            if (CollectionUtil.isNotEmpty(sysCompanyUsers)) {
                for (SysCompanyUser sysCompanyUser : sysCompanyUsers) {
                    DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                    departmentOrUserSimpleDTO.setId(sysCompanyUser.getId());
                    departmentOrUserSimpleDTO.setName(sysCompanyUser.getUserName());
                    departmentOrUserSimpleDTO.setType(2);
                    dtoList.add(departmentOrUserSimpleDTO);
                }
            }
        }

        return dtoList;*/
    }

    // 通过部门id递归查询父列表的Id
    private void getDempartmentParentId(List<Long> demIds, Long departmentId) {
        LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
        departmentWrapper.eq(SysDepartment::getParentId, departmentId);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            for (SysDepartment sysDepartment : sysDepartments) {
                demIds.add(sysDepartment.getId());
                getDempartmentParentId(demIds, sysDepartment.getId());
            }
        }
    }

    // 递归获取部门列表
    private void getNextDeparment(List<SysDepartmentDTO> sysDepartmentDTOS, Long companyId) {
        // 根据获取到上级的目录Id,在获取下级的列表,并进行封装
        for (SysDepartmentDTO sysDepartmentDTO : sysDepartmentDTOS) {
            LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
            departmentWrapper.eq(SysDepartment::getCompanyId, companyId);
            departmentWrapper.eq(SysDepartment::getParentId, sysDepartmentDTO.getId());
            List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(departmentWrapper);
            if (CollectionUtil.isNotEmpty(sysDepartments)) {
                List<SysDepartmentDTO> childrenList = BeanHelper.copyWithCollection(sysDepartments, SysDepartmentDTO.class);
                sysDepartmentDTO.setChildren(childrenList);
                getNextDeparment(childrenList, companyId);
            }
        }
    }

// 根据员工Id获取部门ID以及上层目录iD,保证有序的
    @Override
    public List<Long> findDepartmentIdByCompanyUserId(Long companyUserId) {
        List<Long> depIds = new ArrayList<>();
        if (companyUserId != null){
            // 获取当前员工信息,获取直属部门ID
            SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectById(companyUserId);
            Long departmentId = sysCompanyUser.getDepartmentId();
            depIds.add(departmentId);
            //3. 获取当前部门的上级部门ID , 如果不存在, 直接跳出
            while (true) {
                SysDepartment sysDepartment = sysDepartmentMapper.selectById(departmentId);
                Long parentId = sysDepartment.getParentId();

                if (parentId != null && parentId != 0) {
                    depIds.add(parentId);
                    // 根据parentID再查
                    departmentId = parentId;
                } else {
                    break;
                }
            }
        }
        return depIds;
    }

    // 直接导入员工
    @Override
    public void uploadExcel(MultipartFile excelFile) {
        if (excelFile == null) {
            throw new NCException(ResponseEnum.FILE_NOT_FOUND);
        }
        // 解析文件
        try {
            InputStream inputStream = excelFile.getInputStream();
            EasyExcel.read(inputStream, ExcelMember.class, new ExcelListener(this)).sheet().doRead();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 保存员工
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    SysRoleMapper sysRoleMapper;
    @Autowired
    SysCompanyUserRoleMapper sysCompanyUserRoleMapper;
    @Override
    public void saveExcelUser(List<ExcelMember> excelMembers) {
        if (CollectionUtil.isNotEmpty(excelMembers)) {
            //  保存系统用户数据
            //	需要做校验, 判定手机号、邮箱是否已经被注册； 判定企业员工工号是否被占用；
            for (ExcelMember excelMember : excelMembers) {
                LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
                userWrapper.eq(SysUser::getEmail, excelMember.getEmail());
                userWrapper.eq(SysUser::getMobile, excelMember.getMobile());
                Integer count = sysUserMapper.selectCount(userWrapper);
                if (count != 0) {
                    throw new NCException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
                }
                LambdaQueryWrapper<SysCompanyUser> companyUserWrapper = new LambdaQueryWrapper<>();
                companyUserWrapper.eq(SysCompanyUser::getWorkNumber, excelMember.getWorkNumber());
                Integer count1 = sysCompanyUserMapper.selectCount(companyUserWrapper);
                if (count1 != 0) {
                    throw new NCException(ResponseEnum.WROK_NUM_EXISTS);
                }
                // 保存用户
                SysUser sysUser = new SysUser();
                sysUser.setLastLoginCompanyId(CurrentUserHolder.get().getCompanyId());
                sysUser.setPassword(new BCryptPasswordEncoder().encode("123456"));
                sysUser.setMobile(excelMember.getMobile());
                sysUser.setCreateTime(new Date());
                sysUser.setEmail(excelMember.getEmail());
                sysUser.setStatus(excelMember.getEnable().equals("可用") ? (short) 1 : (short) 0);
                sysUser.setUsername(excelMember.getName());
                sysUserMapper.insert(sysUser);
                // 保存企业员工基本信息
                SysCompanyUser sysCompanyUser = new SysCompanyUser();
                sysCompanyUser.setUserId(sysUser.getId());
                sysCompanyUser.setUserName(sysUser.getUsername());
                sysCompanyUser.setMobile(sysUser.getMobile());
                sysCompanyUser.setEmail(sysUser.getEmail());
                sysCompanyUser.setCreateTime(new Date());
                sysCompanyUser.setCompanyId(CurrentUserHolder.get().getCompanyId());
                sysCompanyUser.setCompanyName(CurrentUserHolder.get().getCompanyName());
                sysCompanyUser.setWorkNumber(excelMember.getWorkNumber());
                sysCompanyUser.setOfficeAddress(excelMember.getWorkAddr());
                sysCompanyUser.setRemark(excelMember.getDesc());
                sysCompanyUser.setEnable(excelMember.getEnable().equals("可用") ? (short) 1 : (short) 0);
                sysCompanyUser.setPost(excelMember.getPosition());
            // 组转员工部门信息
                String departmentName = excelMember.getDepartmentName();
                if (departmentName != null) {
                    LambdaQueryWrapper<SysDepartment> departmentWrapper = new LambdaQueryWrapper<>();
                    departmentWrapper.eq(SysDepartment::getName, departmentName);
                    departmentWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
                    SysDepartment sysDepartment = sysDepartmentMapper.selectOne(departmentWrapper);
                    if (sysDepartment != null) {
                        sysCompanyUser.setDepartmentName(excelMember.getDepartmentName());
                        sysCompanyUser.setDepartmentId(sysDepartment.getId());
                    }
                }
                // 保存员工
                sysCompanyUserMapper.insert(sysCompanyUser);
                // 保存员工角色信息
                String roleName = excelMember.getRoleName();
                if (roleName != null) {
                    LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
                    roleWrapper.eq(SysRole::getRoleDesc, roleName);
                    roleWrapper.eq(SysRole::getCompanyId, CurrentUserHolder.get().getCompanyId());
                    SysRole sysRole = sysRoleMapper.selectOne(roleWrapper);
                    if (sysRole != null) {
                        SysCompanyUserRole sysCompanyUserRole = new SysCompanyUserRole();
                        sysCompanyUserRole.setRoleId(sysRole.getId());
                        sysCompanyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                        sysCompanyUserRole.setCompanyUserId(sysCompanyUser.getId());
                        // 保存员工所对应的角色信息
                        sysCompanyUserRoleMapper.insert(sysCompanyUserRole);
                    }
                }
            }
        }
    }
}
